package com.tomecode.tools.maven.settings.gui.frm.loading;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.ProgressBar;
import org.eclipse.swt.widgets.Shell;

import com.tomecode.tools.maven.settings.RepositoryFactory;
import com.tomecode.tools.maven.settings.gui.event.CancelTask;
import com.tomecode.tools.maven.settings.gui.images.ImageFactory;
import com.tomecode.tools.maven.settings.gui.utils.GuiUtils;
import com.tomecode.tools.maven.settings.gui.utils.SWTResourceManager;
import org.eclipse.swt.layout.grouplayout.GroupLayout;
import org.eclipse.swt.layout.grouplayout.LayoutStyle;

/**
 * Dialog for loading
 * 
 * @author Tomas Frastia
 * @see http://www.tomecode.com or
 *      http://code.google.com/p/maven-settings-editor/
 * 
 */
public final class FrmLoadingPluginGroups extends Dialog implements CancelTask {

	private volatile boolean cancel;
	private volatile LoadingPluginGroupsTask pluginGroupsTask;
	private volatile Shell shlLoading;

	/**
	 * Create the dialog.
	 * 
	 * @param parent
	 * @param style
	 */
	public FrmLoadingPluginGroups(Shell parent) {
		super(parent, SWT.APPLICATION_MODAL | SWT.DIALOG_TRIM);
		setText("Frm Loading");
	}

	/**
	 * Open the dialog.
	 * 
	 * @return the result
	 */
	public final List<String> open(File repository) {
		createContents();

		pluginGroupsTask = new LoadingPluginGroupsTask(this, repository);
		shlLoading.open();
		shlLoading.layout();

		Display display = getParent().getDisplay();

		display.syncExec(pluginGroupsTask);
		while (!shlLoading.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
		return pluginGroupsTask.getList();
	}

	/**
	 * Create contents of the dialog.
	 */
	private final void createContents() {
		shlLoading = new Shell(getParent(), getStyle());
		shlLoading.setImage(ImageFactory.MAVEN_SETTINGS_EDITOR_16);
		shlLoading.setSize(468, 142);
		shlLoading.setText("Loading Plugin Groups");

		Composite composite = new Composite(shlLoading, SWT.NONE);

		if (GuiUtils.isWindows()) {
			composite.setBounds(0, 0, 444, 98);
		}

		ProgressBar progressBar = new ProgressBar(composite, SWT.NONE | SWT.INDETERMINATE);
		progressBar.setState(SWT.ERROR);
		if (GuiUtils.isWindows()) {
			progressBar.setBounds(10, 30, 424, 14);
		}

		Label labelLoadingText = new Label(composite, SWT.NONE);
		labelLoadingText.setFont(SWTResourceManager.getFont("Lucida Grande", 11, SWT.BOLD | SWT.ITALIC));
		if (GuiUtils.isWindows()) {
			labelLoadingText.setBounds(10, 10, 424, 14);
		}
		labelLoadingText.setText("Loading plugin groups...");

		Label label = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL);
		if (GuiUtils.isWindows()) {
			label.setBounds(10, 50, 424, 2);
		}
		Button btnCancel = new Button(composite, SWT.NONE);
		btnCancel.addSelectionListener(new SelectionAdapter() {
			@Override
			public final void widgetSelected(SelectionEvent e) {
				cancel = true;
			}
		});
		if (GuiUtils.isWindows()) {
			btnCancel.setBounds(340, 61, 94, 30);
		}
		btnCancel.setText("Cancel");
		GroupLayout gl_shlLoading = new GroupLayout(shlLoading);
		gl_shlLoading.setHorizontalGroup(gl_shlLoading.createParallelGroup(GroupLayout.LEADING).add(composite, GroupLayout.DEFAULT_SIZE, 462, Short.MAX_VALUE));
		gl_shlLoading.setVerticalGroup(gl_shlLoading.createParallelGroup(GroupLayout.LEADING).add(composite, GroupLayout.DEFAULT_SIZE, 117, Short.MAX_VALUE));
		GroupLayout gl_composite = new GroupLayout(composite);
		gl_composite.setHorizontalGroup(gl_composite.createParallelGroup(GroupLayout.LEADING).add(gl_composite.createSequentialGroup().add(10).add(labelLoadingText, GroupLayout.PREFERRED_SIZE, 430, GroupLayout.PREFERRED_SIZE))
				.add(GroupLayout.TRAILING, gl_composite.createSequentialGroup().addContainerGap(359, Short.MAX_VALUE).add(btnCancel, GroupLayout.PREFERRED_SIZE, 94, GroupLayout.PREFERRED_SIZE).addContainerGap())
				.add(gl_composite.createSequentialGroup().add(10).add(progressBar, GroupLayout.DEFAULT_SIZE, 443, Short.MAX_VALUE).addContainerGap()).add(gl_composite.createSequentialGroup().add(10).add(label, GroupLayout.DEFAULT_SIZE, 443, Short.MAX_VALUE).addContainerGap()));
		gl_composite.setVerticalGroup(gl_composite.createParallelGroup(GroupLayout.LEADING).add(
				gl_composite.createSequentialGroup().add(10).add(labelLoadingText, GroupLayout.PREFERRED_SIZE, 14, GroupLayout.PREFERRED_SIZE).add(6).add(progressBar, GroupLayout.PREFERRED_SIZE, 14, GroupLayout.PREFERRED_SIZE).addPreferredGap(LayoutStyle.RELATED)
						.add(label, GroupLayout.PREFERRED_SIZE, 1, GroupLayout.PREFERRED_SIZE).add(24).add(btnCancel, GroupLayout.PREFERRED_SIZE, 30, GroupLayout.PREFERRED_SIZE).addContainerGap()));
		composite.setLayout(gl_composite);
		shlLoading.setLayout(gl_shlLoading);

	}

	@Override
	public final boolean isCanceled() {
		return cancel;
	}

	/**
	 * Thread for loading list of plugin groups
	 * 
	 * @author Tomas Frastia
	 * @see http://www.tomecode.com or
	 *      http://code.google.com/p/maven-settings-editor/
	 * 
	 */
	private final class LoadingPluginGroupsTask implements Runnable {

		private final File repository;
		private final List<String> pluginGroups;
		private final CancelTask cancelTask;

		private LoadingPluginGroupsTask(CancelTask cancelTask, File repository) {
			this.cancelTask = cancelTask;
			this.pluginGroups = new ArrayList<String>();
			this.repository = repository;
		}

		final List<String> getList() {
			return pluginGroups;
		}

		@Override
		public final void run() {
			RepositoryFactory.parsePluginGroups(repository, pluginGroups, cancelTask);
			cancelTask.threadFinish();
		}
	}

	@Override
	public final void threadFinish() {
		shlLoading.close();
	}

}
